package cn.biplam.back.bean.systemManage.privi;

import java.io.Serializable;
import java.util.ArrayList;

import cn.biplam.back.bean.tree.IndexTableSimpleImp;
import cn.biplam.back.sql.dml.Delete;
import cn.biplam.common.bean.sqlengine.Sql;
import cn.biplam.common.bean.systemManage.privi.UserManageBean;
import cn.biplam.common.bean.tree.IndexTableSimple;
import cn.biplam.common.client.DataFilter;
import cn.biplam.common.client.Operator;
import cn.biplam.common.client.OperatorResult;
import cn.biplam.common.opcode.SysManageCode.RolePriviOptCode;
import cn.biplam.common.opcode.SysManageCode.UserOptCode;
import cn.biplam.common.opcode.SysManageCode.UserPriviOptCode;
import cn.biplam.common.opcode.SysManageCode.UserRoleOptCode;
import cn.biplam.common.paramters.TreeParam.Index_Tree_Node_Type;
import cn.biplam.common.struc.SysStruc.RolePriviStruc;
import cn.biplam.common.struc.SysStruc.UserIndexStruc;
import cn.biplam.common.struc.SysStruc.UserPriviStruc;
import cn.biplam.common.struc.SysStruc.UserRoleStruc;
import cn.biplam.common.struc.SysStruc.UserStruc;
import cn.biplam.common.tools.TOOLS;
import cn.biplam.common.wrapper.ErrorMessage;

/**
 *  用户管理操作类
 * @author XiaoRuxing Dec 3, 20093:37:41 PM
 * @version 1.0
 */
public class UserManageBeanImp extends UserManageBean implements Serializable{

	/**  */
	private static final long serialVersionUID = 231082401724091L;

	static final String User_Index_Table_Name = "users_index";


	/**
	 * 创建用户管理操作类
	 * @param userId  用户ID
	 */
	public UserManageBeanImp(String userId){
		this.userId = userId;
	}

	/**
	 *  插入用户信息
	 * @param groupId   用户分组ID
	 * @param userName  用户名称
	 * @param password  用户密码
	 * @return 返回是否执行成功,和插入的用户ID
	 * @throws ErrorMessage 
	 */
	public OperatorResult insertUser(String groupId,
			String userName,
			String password) throws ErrorMessage{
		return this.insertUser(groupId, userName, password,null,null,null,null,null);
	}

	/**
	 *  插入用户信息
	 * @param groupId    用户分组ID
	 * @param userName  用户名称
	 * @param password  用户密码
	 * @param language  语言
	 * @param userCode  用户代码
	 * @param gender    性别
	 * @param birthday  生日
	 * @param machineName 机器
	 * @return 返回是否执行成功,和插入的用户ID
	 * @throws ErrorMessage 
	 */
	public OperatorResult insertUser(String groupId,
			String userName,
			String password,
			String language,
			String userCode,
			String gender,
			String birthday,
			String machineName) throws ErrorMessage{
		return _insert(groupId, userName, password, language, userCode, gender, birthday, machineName, false);
	}

	/**
	 *  根据用户ID删除用户信息<BR>
	 *  级联操作用户索引表、用户权限表、用户角色表
	 * @param curUserId 用户ID
	 * @return 删除是否成功
	 * @throws ErrorMessage 
	 */
	@Override
	public OperatorResult delUser(String curUserId,boolean getSql) throws ErrorMessage {
		ArrayList<String> sql = new ArrayList<String>();
		
		//1 删除用户角色
		//获取用户角色
		DataFilter filter = new DataFilter();
		filter.put(UserRoleStruc.USER_ID, curUserId);
		OperatorResult userRoles = Operator.get(UserRoleOptCode.Query_By_UserId, this.userId, filter);
		//删除用户与角色的关系
		if(TOOLS.exist(userRoles)){
			String userRoleId;
			do{
				userRoleId = userRoles.getValue(UserRoleStruc.USER_ROLE_ID);
				this.delUserRole(sql, userRoleId);
			}while(userRoles.next());
		}
		//删除用户权限
		this.delUserPrivi(sql, curUserId);
		
		//2 删除用户索引表记录
		IndexTableSimpleImp indexOpt = new IndexTableSimpleImp(this.userId,UserIndexStruc.Table_Name);
		sql.addAll(indexOpt.delete(curUserId, true).getSqls());
		
		//3 删除用户信息
		DataFilter userFilter = new DataFilter();
		userFilter.put(UserStruc.USERID, curUserId);
		sql.addAll(Operator.get(UserOptCode.Del_USer, curUserId, userFilter,true).getSqls());
		
		//返回结果
		if(getSql){
			this.setSql(sql);
			return this.result;
		}else{
			return this.doingDML(sql);
		}
	}

	/**
	 *  删除用户角色
	 * @param userRoleId 用户角色ID
	 * @param getSql 是否返回SQL
	 * @return getSql==ture: 返回删除用户角色的SQL<BR>
	 *         getSql==false: 执行删除用户角色,返回删除是否成功
	 * @throws ErrorMessage 
	 */
	public OperatorResult delUserRole(String userRoleId, boolean getSql) throws ErrorMessage{
		
		//获取用户ID和角色ID
		OperatorResult userRole = this.queryUserRoleById(userRoleId);
		ArrayList<String> sql = new ArrayList<String>();
		if(TOOLS.exist(userRole)){
			delUserRole(userRoleId, 
					userRole.getValue(UserRoleStruc.USER_ID), //用户ID
					userRole.getValue(UserRoleStruc.ROLE_ID), //角色ID
					sql);
		}else{
			throw new ErrorMessage("User Role "+userRoleId+" do not exist at UserMaageBean!");
		}
		
		//返回结果
		if(getSql){
			this.setSql(sql);
			return this.result;
		}else{
			return this.doingDML(sql);
		}
	}

	/**
	 *  删除用户角色
	 * @param userRoleId 用户角色ID
	 * @param userId     用户ID
	 * @param roleId     角色ID
	 * @param getSql 是否返回SQL
	 * @return getSql==ture: 返回删除用户角色的SQL<BR>
	 *         getSql==false: 执行删除用户角色,返回删除是否成功
	 * @throws ErrorMessage 
	 */
	protected void delUserRole(String userRoleId,
			String userId,
			String roleId,
			ArrayList<String> sql) throws ErrorMessage{
		
		//1 删除角色拥有的权限的用户权限
		//获取用户角色独自拥有的权限
		DataFilter filter = new DataFilter();
		filter.put(RolePriviStruc.ROLE_ID,roleId);
		filter.put(UserRoleStruc.USER_ID,userId);
		OperatorResult rolePrivis = Operator.get(RolePriviOptCode.Query_RoleParticular_Privi, 
				this.userId, 
				filter);
		
		//删除用户权限
		if(TOOLS.exist(rolePrivis)){
			String priviId = null;
			do{
				priviId = rolePrivis.getValue(RolePriviStruc.PRIVI_ID);
				delUserPrivi(sql, userId, priviId);
			}while(rolePrivis.next());
		}
		
		//2 删除用户角色
		delUserRole(sql, userRoleId);
	}

	/**
	 *  添加用户角色(级联操作用户权限表)
	 * @param userId 用户ID
	 * @param roleId 角色ID
	 * @param getSql 是否返回SQL
	 * @return getSql==true:返回添加用户角色的SQL
	 *         getSql==false:执行添加用户角色操作,返回用户角色ID和执行是否成功
	 * @throws ErrorMessage 
	 */
	@Override
	public OperatorResult addUserRole(String userId, String roleId,
			boolean getSql) throws ErrorMessage {
		ArrayList<String> sql = new ArrayList<String>();

		//1 在用户角色表中添加新记录
		//判断用户角色关系是否存在,如果存在不添加用户角色
		OperatorResult userRole = queryUserHaveRole(userId, roleId);
		if(TOOLS.exist(userRole))return new OperatorResult();
		DataFilter filter = new DataFilter();
		filter.put(UserRoleStruc.USER_ID, userId);
		filter.put(UserRoleStruc.ROLE_ID, roleId);
		sql.addAll(Operator.get(UserRoleOptCode.Add, this.userId, filter,true).getSqls());
		
		//2 将角色拥有的所有权限授予给用户
		//获取角色的所有权限
		DataFilter roleFilter = new DataFilter();
		roleFilter.put(RolePriviStruc.ROLE_ID, roleId);
		OperatorResult rolePrivis = Operator.get(RolePriviOptCode.Query_By_Role_ID, this.userId, roleFilter);
		//将角色拥有的权限授予用户(权限存在则不授予)
		if(TOOLS.exist(rolePrivis)){
			String priviId = null;
			do{
				priviId = rolePrivis.getValue(RolePriviStruc.PRIVI_ID);
				grantPriviToUser(sql, priviId, userId);
			}while(rolePrivis.next());
		}

		//执行并返回
		if(getSql){
			this.setSql(sql);
			return this.result;
		}else{
			return this.doingDML(sql);
		}
	}

	/**
	 *  添加用户角色(级联操作用户权限表)
	 * @param userId 用户ID
	 * @param roleList 角色列表
	 * @param getSql 是否返回SQL
	 * @return getSql==true:返回添加用户角色的SQL
	 *         getSql==false:执行添加用户角色操作,返回用户角色ID和执行是否成功
	 * @throws ErrorMessage 
	 */
	@Override
	public OperatorResult addUserRoles(String userId, String[] roleList,
			boolean getSql) throws ErrorMessage {
		if(roleList == null) return null;
		ArrayList<String> sql = new ArrayList<String>(); 
		for(String roleId: roleList){
			sql.addAll(this.addUserRole(userId, roleId, true).getSqls());
		}
		//执行并返回
		if(getSql){
			this.setSql(sql);
			return this.result;
		}else{
			return this.doingDML(sql);
		}
	}

	/**
	 *  获取用户是否具有权限
	 * @param userId 用户ID
	 * @param privId 权限ID
	 * @return 是否具有权限
	 * @throws ErrorMessage
	 */
	@Override
	public boolean havePrivi(String userId, String privId) throws ErrorMessage {
		OperatorResult result = this.queryUserHavePrivi(userId, privId);
		if(TOOLS.exist(result)){
			return true;
		}else{
			return false;
		}
	}
	
	/**
	 *  授予用户权限(权限存在则不授予)
	 * @param priviId 权限ID
	 * @param userId  用户ID
	 * @throws ErrorMessage 
	 */
	protected void grantPriviToUser(ArrayList<String> sql ,String priviId, String userId) throws ErrorMessage{
		//查询用户是否有当前权限,有则返回
		OperatorResult userPrivi = this.queryUserHavePrivi(userId, priviId);
		if(TOOLS.exist(userPrivi)){
			return;
		}
		//用户无当前权限,进行授权
		DataFilter filter = new DataFilter();
		filter.put(UserPriviStruc.USER_ID, userId);
		filter.put(UserPriviStruc.PRIVI_ID, priviId);
		OperatorResult addUserPrivi = Operator.get(UserPriviOptCode.Add, this.userId, filter, true);
		sql.addAll(addUserPrivi.getSqls());
	}

	/**
	 *  根据用户ID和角色ID查询用户角色
	 * @return 用户角色
	 * @throws ErrorMessage
	 */
	private OperatorResult queryUserHaveRole(String userId, String roleId) throws ErrorMessage{
		StringBuilder sp = new StringBuilder();
		sp.append(" select * from ");
		sp.append(UserRoleStruc.Table_Name);
		sp.append(" where ");
		sp.append(UserRoleStruc.USER_ID);
		sp.append("='");
		sp.append(userId);
		sp.append("' and ");
		sp.append(UserRoleStruc.ROLE_ID);
		sp.append("='");
		sp.append(roleId);
		sp.append("'");
		OperatorResult userRole = this.doingSelect(new Sql(sp.toString()));
		return userRole;
	}

	/**
	 *  根据用户角色ID查询用户角色
	 * @return 用户角色
	 * @throws ErrorMessage
	 */
	public OperatorResult queryUserRoleById(String userRoleId) throws ErrorMessage{
		StringBuilder sp = new StringBuilder();
		sp.append(" select * from ");
		sp.append(UserRoleStruc.Table_Name);
		sp.append(" where ");
		sp.append(UserRoleStruc.USER_ROLE_ID);
		sp.append("='");
		sp.append(userRoleId);
		sp.append("'");
		OperatorResult userRole = this.doingSelect(new Sql(sp.toString()));
		return userRole;
	}

	/**
	 *  根据用户ID和权限ID查询用户权限
	 * @return 用户权限
	 * @throws ErrorMessage
	 */
	private OperatorResult queryUserHavePrivi(String userId, String priviId) throws ErrorMessage{
		StringBuilder sp = new StringBuilder();
		sp.append(" select * from ");
		sp.append(UserPriviStruc.Table_Name);
		sp.append(" where ");
		sp.append(UserPriviStruc.USER_ID);
		sp.append("='");
		sp.append(userId);
		sp.append("' and ");
		sp.append(UserPriviStruc.PRIVI_ID);
		sp.append("='");
		sp.append(priviId);
		sp.append("'");
		OperatorResult userPrivi = this.doingSelect(new Sql(sp.toString()));
		return userPrivi;
	}

	/**
	 *  插入用户信息<BR>级联操作用户索引表
	 * @param getSql 是否返回SQL ture:返回SQL false:提交到数据库
	 * @return getSql==true时:  插入用户的SQL,当前用户的ID<BR>
	 *         getSql==false时: 提交到数据库是否成功,当前用户的ID<BR>
	 * @throws ErrorMessage
	 */
	private OperatorResult _insert(String groupId,
			String userName,
			String password,
			String language,
			String userCode,
			String gender,
			String birthday,
			String machineName,
			boolean getSql) throws ErrorMessage{
		//获取用户基本信息插入参数列表
		DataFilter filter = getInsertParams(userName, password, language, userCode, gender, birthday, machineName);
		//插入SQL
		ArrayList<String> insertSql = null;

		//获取插入用户基本信息SQL
		OperatorResult result = Operator.get(UserOptCode.Insert_User, userId, filter, true);
		//用户ID
		String userId = result.getLastRowId();
		insertSql = result.getSqls();
		//级联插入用户索引表
		IndexTableSimple userIndex = IndexTableSimple.getNewInstance(userId, User_Index_Table_Name);
		OperatorResult  userIndexInsert =
			userIndex.insertFirst(Index_Tree_Node_Type.OTHER.toString(), 
					groupId, userId, userName, userCode, null, null, true);
		insertSql.addAll(userIndexInsert.getSqls());

		//如果当前是获取SQL模式返回SQL,否则执行插入用户节点
		if(getSql){
			OperatorResult bacResult = new OperatorResult();
			bacResult.setSqls(insertSql);//设置插入SQL
			bacResult.setLastRowId(userId);//设置当前操作的用户ID
			return bacResult;
		}else{
			OperatorResult bacResult = this.doingDML(insertSql);
			bacResult.setLastRowId(userId);
			return bacResult;
		}
	}

	/**
	 *  
	 * @return 插入用户信息所需属性
	 * @throws ErrorMessage 
	 */
	private DataFilter getInsertParams(
			String userName,
			String password,
			String language,
			String userCode,
			String gender,
			String birthday,
			String machineName) throws ErrorMessage{
		DataFilter filter = new DataFilter();
		filter.put(UserStruc.USERNAME, userName);
		filter.put(UserStruc.PASSWORD, password);
		filter.put(UserStruc.LANG, language);
		filter.put(UserStruc.USERCODE, userCode);
		filter.put(UserStruc.SEX, gender);
		filter.put(UserStruc.BIRTHEDAY, birthday);
		filter.put(UserStruc.USER_MACHINE, machineName);
		return filter;
	}
	
	/**
	 *  根据用户ID和权限ID删除用户权限
	 * @param userId  用户ID
	 * @param priviId 权限ID
	 * @throws ErrorMessage 
	 */
	protected void delUserPrivi(ArrayList<String> sql,String userId,String priviId) throws ErrorMessage{
		Delete delete = new Delete(UserPriviStruc.Table_Name);
		StringBuilder sp = new StringBuilder();
		sp.append(UserPriviStruc.USER_ID+"='"+userId+"'");
		sp.append(" and ");
		sp.append(UserPriviStruc.PRIVI_ID+"='"+priviId+"'");
		delete.setWhere(sp.toString());
		sql.add(delete.getSimpleSql());
	}
	
	/**
	 *  根据用户ID删除用户权限
	 * @param userId  用户ID
	 * @throws ErrorMessage 
	 */
	protected void delUserPrivi(ArrayList<String> sql,String userId) throws ErrorMessage{
		Delete delete = new Delete(UserPriviStruc.Table_Name);
		StringBuilder sp = new StringBuilder();
		sp.append(UserPriviStruc.USER_ID+"='"+userId+"'");
		delete.setWhere(sp.toString());
		sql.add(delete.getSimpleSql());
	}
	
	/**
	 *  根据用户角色ID删除用户角色
	 * @param userRoleId 用户角色ID
	 * @throws ErrorMessage 
	 */
	private void delUserRole(ArrayList<String> sql,String userRoleId) throws ErrorMessage{
		Delete delete = new Delete(UserRoleStruc.Table_Name);
		delete.setWhere(UserRoleStruc.USER_ROLE_ID+"='"+userRoleId+"'");
		sql.add(delete.getSimpleSql());
	}
}
